#ifndef __BSP_CAN_H
#define __BSP_CAN_H

#include "bsp.h"


#if HardwareType == Common_Hardware_Type
//CAN1
//TX    PB9
//RX    PB8
#define CAN1_TX_PORT                 GPIOB
#define CAN1_TX_PIN                  GPIO_PIN_9
#define CAN1_TX_PORT_CLK_ENABLE      __HAL_RCC_GPIOB_CLK_ENABLE

#define CAN1_RX_PORT                 GPIOB
#define CAN1_RX_PIN                  GPIO_PIN_8
#define CAN1_RX_PORT_CLK_ENABLE      __HAL_RCC_GPIOB_CLK_ENABLE

//CAN2
//TX    PB13
//RX    PB12
#define CAN2_TX_PORT                 GPIOB
#define CAN2_TX_PIN                  GPIO_PIN_13
#define CAN2_TX_PORT_CLK_ENABLE      __HAL_RCC_GPIOB_CLK_ENABLE

#define CAN2_RX_PORT                 GPIOB
#define CAN2_RX_PIN                  GPIO_PIN_12
#define CAN2_RX_PORT_CLK_ENABLE      __HAL_RCC_GPIOB_CLK_ENABLE


//初始的筛选器结构
typedef struct
{
    uint16_t FilterIdLow;
    uint16_t FilterIdHigh;
    uint16_t FilterMaskIdLow;
    uint16_t FilterMaskIdHigh;
} FilterReg_Hal;

//掩码模式 32位
typedef struct
{
    uint32_t                : 1 ;   // FilterIdLow FilterIdHigh 对应FR1
    uint32_t    RTR         : 1 ;
    uint32_t    IDE         : 1 ;
    uint32_t    ExtID       : 18;
    uint32_t    StdID       : 11;

    uint32_t                : 1 ;   // FilterMaskIdLow FilterMaskIdHigh 对应FR2
    uint32_t    RTR_Mask    : 1 ;
    uint32_t    IDE_Mask    : 1 ;
    uint32_t    ExtID_Mask  : 18;
    uint32_t    StdID_Mask  : 11;
} FilterReg_Mask_32Bit;

//列表模式 32位
typedef struct
{
    uint32_t                : 1 ;   // FilterIdLow FilterIdHigh 对应FR1
    uint32_t    RTR1        : 1 ;
    uint32_t    IDE1        : 1 ;
    uint32_t    ExtID1      : 18;
    uint32_t    StdID1      : 11;

    uint32_t                : 1 ;   // FilterMaskIdLow FilterMaskIdHigh 对应FR2
    uint32_t    RTR2        : 1 ;
    uint32_t    IDE2        : 1 ;
    uint32_t    ExtID2      : 18;
    uint32_t    StdID2      : 11;
} FilterReg_List_32Bit;


//掩码模式 16位
typedef struct
{
    uint16_t                : 3 ;   // FilterIdLow 对应FR1低16位
    uint16_t    IDE1        : 1 ;
    uint16_t    RTR1        : 1 ;
    uint16_t    StdID1      : 11;

    uint16_t                : 3 ;   // FilterIdHigh 对应FR2低16位   
    uint16_t    IDE2        : 1 ;
    uint16_t    RTR2        : 1 ;
    uint16_t    StdID2      : 11;

    uint16_t                : 3 ;   // FilterMaskIdLow 对应FR1高16位
    uint16_t    IDE1_Mask   : 1 ;
    uint16_t    RTR1_Mask   : 1 ;
    uint16_t    StdID1_Mask : 11;

    uint16_t                : 3 ;   //FilterMaskIdHigh  对应FR2高16位 
    uint16_t    IDE2_Mask   : 1 ;
    uint16_t    RTR2_Mask   : 1 ;
    uint16_t    StdID2_Mask : 11;
} FilterReg_Mask_16Bit;

//列表模式 16位
typedef struct
{
    uint16_t                : 3 ;   // FilterIdLow 对应FR1低16位    
    uint16_t    IDE1        : 1 ;
    uint16_t    RTR1        : 1 ;
    uint16_t    StdID1      : 11;

    uint16_t                : 3 ;   // FilterIdHigh 对应FR2低16位    
    uint16_t    IDE2        : 1 ;
    uint16_t    RTR2        : 1 ;
    uint16_t    StdID2      : 11;

    uint16_t                : 3 ;   // FilterMaskIdLow 对应FR1高16位  
    uint16_t    IDE3        : 1 ;
    uint16_t    RTR3        : 1 ;
    uint16_t    StdID3      : 11;

    uint16_t                : 3 ;   //FilterMaskIdHigh  对应FR2高16位   
    uint16_t    IDE4        : 1 ;
    uint16_t    RTR4        : 1 ;
    uint16_t    StdID4      : 11;
} FilterReg_List_16Bit;

typedef union
{
    FilterReg_Hal          hal;     //HAL的参数
    FilterReg_Mask_32Bit   mask32;  //32位掩码模式
    FilterReg_List_32Bit   list32;  //16位列表模式
    FilterReg_Mask_16Bit   mask16;  //32位掩码模式
    FilterReg_List_16Bit   list16;  //16位列表模式
} FilterReg;

typedef enum
{
    MODE_MASK32,
    MODE_LIST32,
    MODE_MASK16,
    MODE_LIST16
} FilterMode;

typedef struct
{
    FilterReg reg;
    FilterMode mode;
    uint32_t FilterFIFO;        //CAN_FILTER_FIFO0 / CAN_FILTER_FIFO1
} FilterUnit, *pFilterUnit;

typedef struct
{
    CAN_RxHeaderTypeDef hdr;
    uint8_t data[8];
} CAN_RX, *P_CAN_RX;


extern CAN_HandleTypeDef CAN1Handle;
extern CAN_HandleTypeDef CAN2Handle;

void CAN_FilterInit(CAN_TypeDef *CANx, FilterUnit unit[], uint16_t num);
void CAN_Init(CAN_TypeDef *CANx, FilterUnit unit[], uint16_t num);

void BSP_CAN1_FIFO0_Callback(P_CAN_RX pcanrx);
void BSP_CAN1_FIFO1_Callback(P_CAN_RX pcanrx);
void BSP_CAN2_FIFO0_Callback(P_CAN_RX pcanrx);
void BSP_CAN2_FIFO1_Callback(P_CAN_RX pcanrx);


#elif HardwareType == Engineer_Hardware_Type
//CAN1已修改
//TX    PA12
//RX    PA11
#define CAN1_TX_PORT                 GPIOA
#define CAN1_TX_PIN                  GPIO_PIN_12
#define CAN1_TX_PORT_CLK_ENABLE      __HAL_RCC_GPIOA_CLK_ENABLE

#define CAN1_RX_PORT                 GPIOA
#define CAN1_RX_PIN                  GPIO_PIN_11
#define CAN1_RX_PORT_CLK_ENABLE      __HAL_RCC_GPIOA_CLK_ENABLE

//CAN2
//TX    PB13
//RX    PB12
#define CAN2_TX_PORT                 GPIOB
#define CAN2_TX_PIN                  GPIO_PIN_13
#define CAN2_TX_PORT_CLK_ENABLE      __HAL_RCC_GPIOB_CLK_ENABLE

#define CAN2_RX_PORT                 GPIOB
#define CAN2_RX_PIN                  GPIO_PIN_12
#define CAN2_RX_PORT_CLK_ENABLE      __HAL_RCC_GPIOB_CLK_ENABLE


//初始的筛选器结构
typedef struct
{
    uint16_t FilterIdLow;
    uint16_t FilterIdHigh;
    uint16_t FilterMaskIdLow;
    uint16_t FilterMaskIdHigh;
} FilterReg_Hal;

//掩码模式 32位
typedef struct
{
    uint32_t                : 1 ;   // FilterIdLow FilterIdHigh 对应FR1
    uint32_t    RTR         : 1 ;
    uint32_t    IDE         : 1 ;
    uint32_t    ExtID       : 18;
    uint32_t    StdID       : 11;

    uint32_t                : 1 ;   // FilterMaskIdLow FilterMaskIdHigh 对应FR2
    uint32_t    RTR_Mask    : 1 ;
    uint32_t    IDE_Mask    : 1 ;
    uint32_t    ExtID_Mask  : 18;
    uint32_t    StdID_Mask  : 11;
} FilterReg_Mask_32Bit;

//列表模式 32位
typedef struct
{
    uint32_t                : 1 ;   // FilterIdLow FilterIdHigh 对应FR1
    uint32_t    RTR1        : 1 ;
    uint32_t    IDE1        : 1 ;
    uint32_t    ExtID1      : 18;
    uint32_t    StdID1      : 11;

    uint32_t                : 1 ;   // FilterMaskIdLow FilterMaskIdHigh 对应FR2
    uint32_t    RTR2        : 1 ;
    uint32_t    IDE2        : 1 ;
    uint32_t    ExtID2      : 18;
    uint32_t    StdID2      : 11;
} FilterReg_List_32Bit;


//掩码模式 16位
typedef struct
{
    uint16_t                : 3 ;   // FilterIdLow 对应FR1低16位
    uint16_t    IDE1        : 1 ;
    uint16_t    RTR1        : 1 ;
    uint16_t    StdID1      : 11;

    uint16_t                : 3 ;   // FilterIdHigh 对应FR2低16位   
    uint16_t    IDE2        : 1 ;
    uint16_t    RTR2        : 1 ;
    uint16_t    StdID2      : 11;

    uint16_t                : 3 ;   // FilterMaskIdLow 对应FR1高16位
    uint16_t    IDE1_Mask   : 1 ;
    uint16_t    RTR1_Mask   : 1 ;
    uint16_t    StdID1_Mask : 11;

    uint16_t                : 3 ;   //FilterMaskIdHigh  对应FR2高16位 
    uint16_t    IDE2_Mask   : 1 ;
    uint16_t    RTR2_Mask   : 1 ;
    uint16_t    StdID2_Mask : 11;
} FilterReg_Mask_16Bit;

//列表模式 16位
typedef struct
{
    uint16_t                : 3 ;   // FilterIdLow 对应FR1低16位    
    uint16_t    IDE1        : 1 ;
    uint16_t    RTR1        : 1 ;
    uint16_t    StdID1      : 11;

    uint16_t                : 3 ;   // FilterIdHigh 对应FR2低16位    
    uint16_t    IDE2        : 1 ;
    uint16_t    RTR2        : 1 ;
    uint16_t    StdID2      : 11;

    uint16_t                : 3 ;   // FilterMaskIdLow 对应FR1高16位  
    uint16_t    IDE3        : 1 ;
    uint16_t    RTR3        : 1 ;
    uint16_t    StdID3      : 11;

    uint16_t                : 3 ;   //FilterMaskIdHigh  对应FR2高16位   
    uint16_t    IDE4        : 1 ;
    uint16_t    RTR4        : 1 ;
    uint16_t    StdID4      : 11;
} FilterReg_List_16Bit;

typedef union
{
    FilterReg_Hal          hal;     //HAL的参数
    FilterReg_Mask_32Bit   mask32;  //32位掩码模式
    FilterReg_List_32Bit   list32;  //16位列表模式
    FilterReg_Mask_16Bit   mask16;  //32位掩码模式
    FilterReg_List_16Bit   list16;  //16位列表模式
} FilterReg;

typedef enum
{
    MODE_MASK32,
    MODE_LIST32,
    MODE_MASK16,
    MODE_LIST16
} FilterMode;

typedef struct
{
    FilterReg reg;
    FilterMode mode;
    uint32_t FilterFIFO;        //CAN_RX_FIFO0 / CAN_RX_FIFO1
} FilterUnit, *pFilterUnit;


typedef struct
{
    CAN_RxHeaderTypeDef hdr;
    uint8_t data[8];
} CAN_RX, *P_CAN_RX;


extern CAN_HandleTypeDef CAN1Handle;
extern CAN_HandleTypeDef CAN2Handle;

void CAN_Init(CAN_TypeDef *CANx, FilterUnit unit[], uint16_t num);

void BSP_CAN1_FIFO0_Callback(P_CAN_RX pcanrx);
void BSP_CAN1_FIFO1_Callback(P_CAN_RX pcanrx);
void BSP_CAN2_FIFO0_Callback(P_CAN_RX pcanrx);
void BSP_CAN2_FIFO1_Callback(P_CAN_RX pcanrx);


#endif

#endif
